package com.lock.service;

import com.lock.entiy.Product;
import com.lock.mapper.ProductMapper;
import com.lock.util.RedisLockUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 悲观锁实现
 */
@Service
@Transactional
public class PessimisticLockService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private RedisLockUtil redisLockUtil;
    // 锁缓存：为每个商品ID分配一个锁对象
    private final ConcurrentHashMap<Long, Object> locks = new ConcurrentHashMap<>();

    /**
     * 数据库悲观锁：扣减库存
     */
    public boolean decreaseStockByDbLock(Long productId, int quantity) {
        // 使用SELECT ... FOR UPDATE获取行锁
        Product product = productMapper.selectByIdForUpdate(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        if (product.getStock() < quantity) {
            return false; // 库存不足
        }

        product.setStock(product.getStock() - quantity);
        productMapper.updateById(product);
        return true;
    }

    /**
     * Redis分布式锁：扣减库存
     */
    public boolean decreaseStockByRedisLock(Long productId, int quantity) {
        String lockKey = "lock:product:" + productId;
        String requestId = UUID.randomUUID().toString();
        boolean locked = false;

        try {
            // 获取锁（10秒过期，防止死锁）
            locked = redisLockUtil.tryLock(lockKey, requestId, 10, TimeUnit.SECONDS);
            if (!locked) {
                return false; // 获取锁失败
            }

            // 查询并扣减库存（无锁，由Redis锁保证互斥）
            Product product = productMapper.selectByIdForUpdate(productId);

            if (product.getStock() < quantity) {
                return false; // 库存不足
            }

            product.setStock(product.getStock() - quantity);
            productMapper.insert(product);
            return true;
        } finally {
            // 释放锁
            if (locked) {
                redisLockUtil.releaseLock(lockKey, requestId);
            }
        }
    }

    /**
     * 使用 synchronized 实现库存扣减（JVM 内悲观锁）
     */
    public boolean decreaseStockBySynchronized(Long productId, int quantity) {
        // 获取或创建商品对应的锁对象
        Object lock = locks.computeIfAbsent(productId, k -> new Object());

        // 加锁
        synchronized (lock) {
            try {
                // 查询库存
                Product product = productMapper.selectById(productId);
                if (product == null || product.getStock() < quantity) {
                    return false;
                }

                // 扣减库存
                product.setStock(product.getStock() - quantity);
                productMapper.updateById(product);
                return true;
            } catch (Exception e) {
                System.out.println("库存扣减异常");
                return false;
            }
        }
    }
}
